package com.mmall.service;

import com.google.common.collect.Lists;
import com.mmall.beans.CacheKeyConstants;
import com.mmall.common.RequestHolder;
import com.mmall.dao.SysAclMapper;
import com.mmall.dao.SysRoleAclMapper;
import com.mmall.dao.SysRoleUserMapper;
import com.mmall.model.SysAcl;
import com.mmall.model.SysUser;
import com.mmall.util.JsonMapper;
import com.mmall.util.StringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Auther 19135
 * @Date 2019/3/26 21:36
 * @Description ${权限核心service}$
 */
@Service
public class SysCoreService {

	@Resource
	private SysAclMapper sysAclMapper;

	@Resource
	private SysRoleUserMapper sysRoleUserMapper;

	@Resource
	private SysRoleAclMapper sysRoleAclMapper;

	@Resource
	private SysCacheService sysCacheService;

	//获取当前登录用户所拥有的权限
	public List<SysAcl> getCurrentUserAclList(){
		int userId = RequestHolder.getCurrentUser().getId();
		return getUserAclList(userId);
	}

	//获得该角色拥有的所有权限
	public List<SysAcl> getRoleAclList(int roleId){
		//获取该角色拥有的所有角色id
		List<Integer> aclIdList = sysRoleAclMapper.getAclIdListByRoleIdList(Lists.<Integer>newArrayList(roleId));
		if (CollectionUtils.isEmpty(aclIdList)){
			return Lists.newArrayList();
		}
		return sysAclMapper.getByIdList(aclIdList);
	}

	public List<SysAcl> getUserAclList(int userId){
		if (isSuperAdmin()){
			return sysAclMapper.getAll();
		}
		//获取该用户所有的角色
		List<Integer> userRoleIdList = sysRoleUserMapper.getRoleIdListByUserId(userId);
		if (CollectionUtils.isEmpty(userRoleIdList)){
			return Lists.newArrayList();
		}
		//获该角色集合拥有的所有权限id
		List<Integer> aclIdListByRoleIdList = sysRoleAclMapper.getAclIdListByRoleIdList(userRoleIdList);
		if (CollectionUtils.isEmpty(aclIdListByRoleIdList)){
			return Lists.newArrayList();
		}
		return sysAclMapper.getByIdList(userRoleIdList);
	}

	//判断当前登录的用户是否有权限访问该url
	public boolean hasUrlAcl(String url){
		if (isSuperAdmin()){
			return true;
		}
		//查询可以访问该页面的权限
		List<SysAcl> aclList = sysAclMapper.getByUrl(url);
		if (CollectionUtils.isEmpty(aclList)) {
			return true;
		}
		List<SysAcl> userAclList = getCurrentUserAclListFromCache();
		//将权限去重
		Set<Integer> userAclIdSet = userAclList.stream().map(acl -> acl.getId()).collect(Collectors.toSet());

		boolean hasValidAcl = false;
		//规则，只要有一个权限点有权限，那么我们就认为有访问权限
		for (SysAcl acl:aclList){
			//判断一个用户是否具有某个权限点的访问权限
			if (acl == null || acl.getStatus() != 1 ){
				continue;
			}
			hasValidAcl = true;
			if (userAclIdSet.contains(acl.getId())) {
				return true;
			}
		}
		return false;
	}


	public boolean isSuperAdmin() {
		// 这里是我自己定义了一个假的超级管理员规则，实际中要根据项目进行修改
		// 可以是配置文件获取，可以指定某个用户，也可以指定某个角色
		SysUser sysUser = RequestHolder.getCurrentUser();
		if (sysUser.getMail().contains("admin")) {
			return true;
		}
		return false;
	}


	public List<SysAcl> getCurrentUserAclListFromCache(){
		int userId = RequestHolder.getCurrentUser().getId();
		String cacheValue = sysCacheService.getFormCache(CacheKeyConstants.USER_ACLS, String.valueOf(userId));
		//如果缓存中不存在的话查询该用户权限并保存入缓存
		if (StringUtils.isBlank(cacheValue)){
			List<SysAcl> aclList = getCurrentUserAclList();
			if (CollectionUtils.isNotEmpty(aclList)){
				sysCacheService.saveCache(JsonMapper.obj2String(aclList),600,CacheKeyConstants.USER_ACLS, String.valueOf(userId));
			}
			return aclList;
		}
		return JsonMapper.string2Obj(cacheValue, new TypeReference<List<SysAcl>>() {
		});
	}







}
